package com.core.springmvc;

import com.core.netty.http.work.HttpMyReponse;
import com.core.netty.http.work.HttpMyRequest;
import com.core.netty.http.work.HttpMySerlvet;
import com.core.netty.http.work.MySerlvetUrl;
import com.core.spring.DefaultMyApplication;
import com.core.spring.IocBeanFactory;
import com.core.springaop.MyAopFactory;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@MySerlvetUrl("/*")
public class MyDispatcherServlet extends HttpMySerlvet {

    private Map<String, Method> handlerMapping = new HashMap<>();

    private Map<String, Object> controllerMap = new HashMap<>();

    private Map<String, Class<?>> controllerClassMap = new HashMap<>();


    @Override
    public void init() {
        //初始化HandlerMapping(将url和method对应上)
        initHandlerMapping();
    }

    @Override
    public void destory() {

    }

    @Override
    public void domain(HttpMyRequest req, HttpMyReponse rep) {
        //处理请求
        try {
            doDispatch(req, rep);
        } catch (Exception e) {
            e.printStackTrace();
            rep.fullWrite(e.getMessage());
        }
    }


    private void doDispatch(HttpMyRequest req, HttpMyReponse rep) throws Exception {
        if (handlerMapping.isEmpty()) {
            return;
        }
//       if("multipart/form-data".equals(req.getContentType())){
//          MultipartResolver resolver = new CommonsMultipartResolver(req.getSession().getServletContext());
//          MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(req);
//
//        }

        String url = req.getUrl().replaceAll("/+", "/");

        if (!this.handlerMapping.containsKey(url)) {
            rep.fullWrite("404 NOT FOUND! 你是一个大王八");
            return;
        }

        Method method = this.handlerMapping.get(url);

        //获取方法的参数列表
        Parameter[] parameters = method.getParameters();

        //获取请求的参数
        Map<String, String> parameterMap = req.getParameterMap();

        //保存参数值
        Object[] paramValues = new Object[parameters.length];

        //方法的参数列表
        for (int i = 0; i < parameters.length; i++) {
            //根据参数名称，做某些处理
            String paramType = parameters[i].getType().getSimpleName();
            String paramName = parameters[i].getName();

            if (paramType.equals("HttpMyRequest")) {
                //参数类型已明确，这边强转类型
                paramValues[i] = req;
                continue;
            } else if (paramType.equals("HttpMyReponse")) {
                paramValues[i] = rep;
                continue;
            } else {
                paramValues[i] = parameterMap.get(paramName);

            }
        }
        //利用反射机制来调用
        try {
            //aop动态代理
            Class clazz = controllerClassMap.get(url);
            Object o = MyAopFactory.getSub(clazz);
            //method.invoke(controllerMap.get(url), paramValues);//第一个参数是method所对应的实例 在ioc容器中
            method.invoke(o, paramValues);
        } catch (Exception e) {
            e.printStackTrace();
            rep.fullWrite(e.getMessage());
        }
    }


    private void initHandlerMapping() {
        List<Class<?>> requestClassList = ((DefaultMyApplication) IocBeanFactory.getInstant()).getRequestClassList();

        if (requestClassList.isEmpty()) {
            return;
        }
        try {
            for (Class<?> clazz : requestClassList) {

                //拼url时,是controller头的url拼上方法上的url
                String baseUrl = "";
                if (clazz.isAnnotationPresent(MyRequestMapping.class)) {
                    MyRequestMapping annotation = clazz.getAnnotation(MyRequestMapping.class);
                    baseUrl = annotation.value();
                }
                Method[] methods = clazz.getMethods();
                for (Method method : methods) {
                    if (!method.isAnnotationPresent(MyRequestMapping.class)) {
                        continue;
                    }
                    MyRequestMapping annotation = method.getAnnotation(MyRequestMapping.class);
                    String url = annotation.value();

                    url = (baseUrl + "/" + url).replaceAll("/+", "/");
                    handlerMapping.put(url, method);
                    controllerMap.put(url, clazz.newInstance());
                    controllerClassMap.put(url, clazz);

                }

            }
            requestClassList = null;
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 把字符串的首字母小写
     *
     * @param name
     * @return
     */
    private String toLowerFirstWord(String name) {
        char[] charArray = name.toCharArray();
        charArray[0] += 32;
        return String.valueOf(charArray);
    }


}
